﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace PyNet
{
    public partial class frmConsole : Form
    {
        public delegate void AddRTBItemDel(Color color, string text);
        public delegate void AddListViewItem(string item);
        public delegate void RemoveListViewItem(string item);
        public delegate void AlterListViewItem(string item, string flag, int ping, string tooltip);
        public delegate void SetBarDel(int now, int cap);

        public frmConsole()
        {
            InitializeComponent();
        }

        private void frmConsole_Load(object sender, EventArgs e)
        {
            this.Text = "PyNet # " +
                Application.ProductVersion;

            AddText("Black", "Welcome to PyNet " + Application.ProductVersion + " by VBScript");
            AddText("Black", "You can view the latest updates and other information at: http://python.bot.nu/");

            txtCommand.Items.Add("/server start");
            txtCommand.Items.Add("/server stop");
            txtCommand.Items.Add("/server settings");

            txtCommand.Items.Add("/kill <user>");
            txtCommand.Items.Add("/pingall");
        }

        private void _AddRTBItem(Color color, string text)
        {
            rtbChat.SelectionStart = rtbChat.Text.Length;
            rtbChat.SelectionLength = 0;
            rtbChat.SelectionColor = color;
            rtbChat.SelectedText = text;
            rtbChat.SelectionStart = rtbChat.Text.Length;
            rtbChat.SelectionLength = 0;
            rtbChat.ScrollToCaret();
        }

        public void AddRTBItem(Color color, string text)
        {
            if (this.InvokeRequired)
            {
                rtbChat.Invoke(new AddRTBItemDel(_AddRTBItem), new object[] { color, text });
            } else {
                _AddRTBItem(color, text);
            }
        }

        public void AddText(params string[] items)
        {
            DateTime date = DateTime.Now;
            string timestamp = String.Format("{0:hh:mm:ss}", date);

            AddRTBItem(Color.Black, "[" + timestamp + "] ");
            for (int i = 0; i < items.Length; i += 2)
            {
                string color = items[i];
                string text = items[i + 1];

                AddRTBItem(Color.FromName(color), text);
            }

            AddRTBItem(Color.White, "\r\n");
        }

        private void _AddListItem(string name)
        {
            ListViewItem item = new ListViewItem(name);
            item.SubItems.Add("");
            item.SubItems.Add("0");
            lvClients.Items.Add(item);
        }

        public void AddListItem(string name)
        {
            if (this.InvokeRequired)
            {
                lvClients.Invoke(new AddListViewItem(_AddListItem), name);
            }
            else
            {
                _AddListItem(name);
            }
        }

        private void _RemoveListItem(string name)
        {
            if (name == "")
            {
                lvClients.Items.Clear();
                return;
            }

            for (int i = 0; i < lvClients.Items.Count;)
            {
                if (lvClients.Items[i].Text == name)
                {
                    lvClients.Items.RemoveAt(i);
                    break;
                }
                else
                {
                    i++;
                }
            }
        }

        public void RemoveListItem(string name)
        {
            if (this.InvokeRequired)
            {
                lvClients.Invoke(new RemoveListViewItem(_RemoveListItem), name);
            }
            else
            {
                _RemoveListItem(name);
            }
        }

        private void _AlterListItem(string name, string flag, int ping, string tooltip)
        {
            for (int i = 0; i < lvClients.Items.Count; )
            {
                if (lvClients.Items[i].Text == name)
                {
                    ListViewItem item = lvClients.Items[i];
                    item.SubItems[2].Text = ping.ToString();
                    item.SubItems[0].Text = name;
                    item.SubItems[1].Text = flag;
                    item.ToolTipText = tooltip;
                    break;
                }
                else
                {
                    i++;
                }
            }
        }

        public void AlterListItem(string name, string flag, int ping, string tooltip)
        {
            if (this.InvokeRequired)
            {
                lvClients.Invoke(new AlterListViewItem(_AlterListItem), name, flag, ping, tooltip);
            }
            else
            {
                _AlterListItem(name, flag, ping, tooltip);
            }
        }

        public void SetLabel(string text)
        {
            lblStatus.Text = text;
            Program.GetSmallConsole.SetLabel(text);
        }

        public void _SetBar(int now, int cap)
        {
            int val = (now / cap) * 100;
            barLoad.Value = val;
        }

        public void SetBar(int now, int cap)
        {
            if (this.InvokeRequired)
            {
                barLoad.Invoke(new SetBarDel(_SetBar), now, cap);
            }
            else
            {
                _SetBar(now, cap);
            }
        }

        public void SetTitle(string text)
        {
            if (text != "")
            {
                this.Text = "PyNet # " +
                    Application.ProductVersion +
                    " - " + text;
            }
            else
            {
                this.Text = "PyNet # " +
                    Application.ProductVersion;
            }
        }

        private void txtCommand_Process()
        {
            string command = Regex.Split(txtCommand.Text, "\r\n")[0];
            txtCommand.Text = "";
            if (command.StartsWith("/"))
            {
                string[] commands = Regex.Split(command.TrimStart('/'), " ");
                string cmd = commands[0].ToLower();
                if (cmd == "server")
                {
                    if (commands[1] == "start")
                    {
                        Program.GetServer.StartServerLoop();
                    }
                    else if (commands[1] == "stop")
                    {
                        Program.GetServer.StopServerLoop();
                    }
                    else if (commands[1] == "settings")
                    {
                        frmSettings settings = new frmSettings();
                        settings.Show();
                    }
                }
                else if (cmd == "kill")
                {
                    string name = String.Join(" ", commands, 1, commands.Length - 1);
                    Program.GetServer.FindAndRemoveClient(name);
                }
                else if (cmd == "pingall")
                {
                    Program.GetServer.SendGlobalPingRequest();
                }
            }
            else
            {
                Program.GetServer.Channels[Program.GetServer.AdminLobbyID].TalkUser("ServerConsole", command);
            }
        }

        private void txtCommand_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
                txtCommand_Process();
        }

        private void txtCommand_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }

        private void btnChannels_Click(object sender, EventArgs e)
        {
            txtCommand.Text = "/server settings";
            txtCommand_Process();
        }

        private void btnShrink_Click(object sender, EventArgs e)
        {
            Program.GetSmallConsole.Show();
            this.Hide();
        }
    }
}
